package md.mru.frontend.controllers;

import md.mru.core.domains.type.RolesType;
import md.mru.core.domains.type.SystemTagType;
import md.mru.core.dtos.*;
import md.mru.core.service.AdministrationService;
import md.mru.core.service.FolderService;
import md.mru.core.service.OrderService;
import org.apache.log4j.Logger;
import org.springframework.security.crypto.bcrypt.BCrypt;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author sergiu.marin
 * @since 31/05/2014.
 */
@ManagedBean
@SessionScoped
public class AdministrationBean extends BackingBean implements Serializable {

    Logger logger = Logger.getLogger(AdministrationBean.class);

    private static final long serialVersionUID = -8907649493051853388L;

    @ManagedProperty(value = "#{administrationService}")
    private AdministrationService administrationService;

    @ManagedProperty(value = "#{folderAdministrationBean}")
    private FolderAdministrationBean folderAdministrationBean;

    @ManagedProperty(value = "#{folderService}")
    private FolderService folderService;

    @ManagedProperty(value = "#{authenticationBean}")
    private AuthenticationBean authenticationBean;

    @ManagedProperty(value = "#{orderService}")
    private OrderService orderService;

    /*private List<OrderTypeGroupDto> orderTypeGroups;*/
    private List<OrderTypeDto> orderTypes;
    /*private OrderTypeDto selectedOrderType;*/
    /*private OrderPatternDto selectedOrderPattern;*/
    /*@ManagedProperty(value = "#{objectMappingConverter}")
    private ObjectMappingConverter objectMappingConverter;*/

    private List<UserDto> users;
    private List<UserGroupDto> groups;
    private List<SystemTagDto> systemTags;
    private UserGroupDto selectedUserGroup;
    private SystemTagDto selectedSystemTag;
    private UserDto selectedUser;
    private List<FolderDto> unAssociatedFolders;
    private RolesType[] roles = RolesType.values();

    public String loadUsers() {
        users = administrationService.getAllUsers(authenticationBean.getLoginUser().getUser().getId());
        this.unAssociatedFolders = folderService.getUnAssociatedFolders();
        getObjectMappingConverter().mapObjectList(unAssociatedFolders);
        this.groups = administrationService.getGroups();
        getObjectMappingConverter().mapObjectList(groups);
        return "list-users";
    }

    public String loadGroups() {
        groups = administrationService.getGroups();
        return "list-groups";
    }

    public String loadSystemTags() {
        systemTags = administrationService.getSystemTags();
        return "list-system-tags";
    }

    /*public String initOrderTemplates() {
        if (this.orderTypeGroups == null) {
            this.orderTypeGroups = orderService.loadOrderTypeGroups();
            getObjectMappingConverter().mapObjectList(orderTypeGroups);
        }
        this.orderTypes = null;
        this.selectedOrderType = null;
        this.selectedOrderPattern = null;
        return "order-templates";
    }*/

    /*public void onPatternOrderGroupSelect(AjaxBehaviorEvent event) {
        OrderTypeGroupDto value = (OrderTypeGroupDto) ((UIOutput) event.getSource()).getValue();
        this.orderTypes = orderService.loadOrderTypesByGroup(value.getId());
        getObjectMappingConverter().mapObjectList(orderTypes);
        this.selectedOrderType = null;
        this.selectedOrderPattern = null;
    }*/

    /*public void onOrderTypeSelect() {
        this.selectedOrderPattern = null;
    }*/

    /*public void onOrderPatternSelect(AjaxBehaviorEvent event) {
        String value = (String) ((UIOutput) event.getSource()).getValue();
        for (OrderPatternDto orderPattern : this.selectedOrderType.getOrderPatterns()) {
            if (orderPattern.getName().equalsIgnoreCase(value)) {
                this.selectedOrderPattern = orderPattern;
                return;
            }
        }
        this.selectedOrderPattern.setName(value);
    }*/

    public List<FolderDto> complete(String suggestion) {
        List<FolderDto> suggestions = new ArrayList<FolderDto>();

        for (FolderDto f : unAssociatedFolders) {
            if (f.getFirstName().toLowerCase().startsWith(suggestion.toLowerCase())
                    || f.getLastName().toLowerCase().startsWith(suggestion.toLowerCase())) {
                suggestions.add(f);
            }
        }
        return suggestions;
    }

    /*public void onFolderSelect() {
        String generatedValue = this.selectedUser.getFolder().getFirstName().toLowerCase()
                + "." + this.selectedUser.getFolder().getLastName().toLowerCase();
        this.selectedUser.setUsername(generatedValue);
        this.selectedUser.setGeneratedPassword(generatedValue);
    }*/

    /*public void resetPassword() {
        this.selectedUser.setPassword(null);
        this.selectedUser.setGeneratedPassword(this.selectedUser.getUsername());
        this.selectedUser.setPasswordResetted(true);
    }*/

    public void addNewUser() {
        this.selectedUser = new UserDto();
    }

    public void addNewGroup() {
        this.selectedUserGroup = new UserGroupDto();
    }

    public void addNewSystemTag() {
        this.selectedSystemTag = new SystemTagDto(SystemTagType.NO_SYSTEM_TAG);
    }

    public void saveUserProfile() {
        selectedUser.setPassword(BCrypt.hashpw(selectedUser.getPassword(), BCrypt.gensalt()));
        this.administrationService.saveUser(selectedUser);
    }

    /*public void onEditorSaveEvent() {
        if (selectedOrderPattern.getId() == 0) {
            this.selectedOrderType.getOrderPatterns().add(selectedOrderPattern);
        }
        this.administrationService.saveOrderPattern(selectedOrderPattern);
        BeanUtils.addSimpleMessage("Salvat cu success.");
    }*/

    /*public void deleteOrderPattern() {
        this.administrationService.deleteOrderPattern(selectedOrderPattern.getId());
        this.selectedOrderType.getOrderPatterns().remove(selectedOrderPattern);
        this.selectedOrderPattern = null;
    }*/

    /*public void saveUser() {
        if (selectedUser.getGeneratedPassword() != null) {
            this.selectedUser.setPassword(BCrypt.hashpw(selectedUser.getGeneratedPassword(), BCrypt.gensalt()));
        }
        long userId = administrationService.saveUser(selectedUser);
        if (selectedUser.getId() == 0) {
            selectedUser.setId(userId);
            users.add(selectedUser);
        }

        //TODO - send inform mail
        if (!this.selectedUser.isWasInformed() && this.selectedUser.isInformed()) {
            BeanUtils.addInfoMessage("An email with account user details must be sent.");
        }

        //TODO - send inform mail
        if (this.selectedUser.isPasswordResetted()) {
            BeanUtils.addInfoMessage("An email with new pass was sent.");
        }
        logger.debug("Inform e-mail was sent.");
    }*/

    public void editProfile() {
        this.selectedUser = new UserDto(authenticationBean.getLoginUser().getUser());
    }

    public void saveGroup() {
        long groupId = administrationService.saveGroup(selectedUserGroup);
        if (selectedUserGroup.getId() == 0) {
            selectedUserGroup.setId(groupId);
        }
        groups.add(selectedUserGroup);
    }

    public void saveSystemTag() {
        long systemTagId = administrationService.saveSystemTag(selectedSystemTag);
        if (selectedSystemTag.getId() == 0) {
            selectedSystemTag.setId(systemTagId);
        }
        systemTags.add(selectedSystemTag);
    }

    public void deleteUser(UserDto user) {
        administrationService.deleteUser(user.getId());
        this.users.remove(user);
    }

    public void deleteUserGroup(UserGroupDto userGroup) {
        administrationService.deleteUserGroup(userGroup.getId());
        this.groups.remove(userGroup);
    }

    public void deleteSystemTag(SystemTagDto systemTag) {
        administrationService.deleteSystemTag(systemTag.getId());
        this.systemTags.remove(systemTag);
    }

    /*public void newPatternHandler() {
        String orderTemplateHeader = this.decorateTemplateHeaderValue(administrationService.getOrderTemplateHeader());
        this.selectedOrderPattern = new OrderPatternDto(orderTemplateHeader, selectedOrderType);
    }*/

    /*public String getOrderTemplate() {
        if (selectedOrderPattern == null) {
            return null;
        }
        *//*
        if (selectedOrderPattern.getId() == 0) {
            String orderTemplateHeader = this.decorateTemplateHeaderValue(administrationService.getOrderTemplateHeader());
            this.selectedOrderPattern.setPattern(orderTemplateHeader);
        }*//*
        return this.selectedOrderPattern.getPattern();
    }*/

    /*public String decorateTemplateHeaderValue(String value) {
        String order = "Order</br>nr. @NUMAR_ORDIN";
        return value.replace("#ORDER_NR", order);
    }*/

    /*public void setOrderTemplate(String value) {
        this.selectedOrderPattern.setPattern(value);
    }*/

    /*public boolean showSystemTagEdit(SystemTagDto systemTag) {
        return !systemTag.getSystemTagType().equals(SystemTagType.READ_ONLY_SYSTEM_TAG);
    }*/

    public boolean noSystemTagType() {
        return this.noSystemTagType(selectedSystemTag);
    }

    public boolean noSystemTagType(SystemTagDto systemTag) {
        return systemTag.getSystemTagType().equals(SystemTagType.NO_SYSTEM_TAG);
    }

    public boolean editUserDisabled() {
        return this.selectedUser.getId() != 0;
    }

    public List<UserDto> getUsers() {
        return users;
    }

    public List<UserGroupDto> getGroups() {
        return groups;
    }

    public UserGroupDto getSelectedUserGroup() {
        return selectedUserGroup;
    }

    public void setSelectedUserGroup(UserGroupDto selectedUserGroup) {
        this.selectedUserGroup = selectedUserGroup;
    }

    public SystemTagDto getSelectedSystemTag() {
        return selectedSystemTag;
    }

    public void setSelectedSystemTag(SystemTagDto selectedSystemTag) {
        this.selectedSystemTag = selectedSystemTag;
    }

    public UserDto getSelectedUser() {
        return selectedUser;
    }

    public void setSelectedUser(UserDto selectedUser) {
        this.selectedUser = selectedUser;
    }

    public List<FolderDto> getUnAssociatedFolders() {
        return unAssociatedFolders;
    }

    public void setUnAssociatedFolders(List<FolderDto> unAssociatedFolders) {
        this.unAssociatedFolders = unAssociatedFolders;
    }

    public void setAdministrationService(AdministrationService administrationService) {
        this.administrationService = administrationService;
    }

    public void setFolderAdministrationBean(FolderAdministrationBean folderAdministrationBean) {
        this.folderAdministrationBean = folderAdministrationBean;
    }

    public void setFolderService(FolderService folderService) {
        this.folderService = folderService;
    }

    public RolesType[] getRoles() {
        return roles;
    }

    public void setAuthenticationBean(AuthenticationBean authenticationBean) {
        this.authenticationBean = authenticationBean;
    }

    public List<SystemTagDto> getSystemTags() {
        return systemTags;
    }

    /*public List<OrderTypeGroupDto> getOrderTypeGroups() {
        return orderTypeGroups;
    }*/

    public List<OrderTypeDto> getOrderTypes() {
        return orderTypes;
    }

    /*public List<OrderPatternDto> getOrderPatterns() {
        List<OrderPatternDto> orderPatterns = getSelectedOrderType().getOrderPatterns();
        getObjectMappingConverter().mapObjectList(orderPatterns);
        return orderPatterns;
    }*/

    /*public OrderTypeDto getSelectedOrderType() {
        *//*if (selectedOrderType == null) {
            selectedOrderType = new OrderTypeDto();
        }*//*
        return selectedOrderType;
    }

    public void setSelectedOrderType(OrderTypeDto selectedOrderType) {
        this.selectedOrderType = selectedOrderType;
    }*/

    public void setOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    /*public OrderPatternDto getSelectedOrderPattern() {
        return selectedOrderPattern;
    }

    public void setSelectedOrderPattern(OrderPatternDto selectedOrderPattern) {
        this.selectedOrderPattern = selectedOrderPattern;
    }*/
}
